home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir34
/
thindi.zip
/
THISRC.ZIP
/
THINDISK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-14
|
87KB
|
2,674 lines
//===========================================================
// ThinDisk - A Program to help thin out disk clutter
// Copyright (C) 1994 Douglas Boling
//
// Revision History:
//
// 1.0 Initial Release
//
//===========================================================
// Returns no. of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))
#define SPECNAMELEN 32
//-----------------------------------------------------------
// Include files
//-----------------------------------------------------------
#include "windows.h"
#include "dos.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "direct.h"
#include "ctype.h"
#include "thindisk.h"
#include "statbar.h"
//-----------------------------------------------------------
// Global data
//-----------------------------------------------------------
// Message dispatch table for MainWindowProc
struct decodeUINT MainMessages[] = {
WM_CREATE, DoCreateMain,
WM_DRAWITEM, DoDrawItemMain,
WM_MEASUREITEM, DoMeasureItemMain,
WM_INITMENU, DoInitMenuMain,
WM_SETFOCUS, DoSetFocusMain,
WM_SIZE, DoSizeMain,
WM_COMMAND, DoCommandMain,
WM_CLOSE, DoCloseMain,
WM_DESTROY, DoDestroyMain,
};
// Command Message dispatch for MainWindowProc
struct decodeCMD MainMenuItems[] = {
// IDD_FLIST, DoMainCtlFList,
IDM_REFRESH, DoMainMenuRefresh,
IDM_MOVE, DoMainMenuMCD,
IDM_COPY, DoMainMenuMCD,
IDM_DELETE, DoMainMenuMCD,
IDM_EXIT, DoMainMenuExit,
IDM_FIND, DoMainMenuFind,
IDM_FINDNEXT, DoMainMenuFind,
IDM_FINDPREV, DoMainMenuFind,
IDM_SORTUPDN, DoMainMenuInvert,
IDM_SHOWSIZE, DoMainMenuShow,
IDM_SHOWDATE, DoMainMenuShow,
IDM_SHOWATTRIB, DoMainMenuShow,
IDM_SHOWPATH, DoMainMenuShow,
IDM_SORTNAME, DoMainMenuSort,
IDM_SORTEXT, DoMainMenuSort,
IDM_SORTSIZE, DoMainMenuSort,
IDM_SORTDATE, DoMainMenuSort,
IDM_INCLUDE, DoMainMenuInclude,
IDM_INCLUDEEDIT, DoMainMenuIncludeEdit,
IDM_INCLUDEDEL, DoMainMenuIncludeDel,
IDM_INCLUDEALL, DoMainMenuIncludeSet,
IDM_INCLUDEALL+1, DoMainMenuIncludeSet,
IDM_INCLUDEALL+2, DoMainMenuIncludeSet,
IDM_INCLUDEALL+3, DoMainMenuIncludeSet,
IDM_INCLUDEALL+4, DoMainMenuIncludeSet,
IDM_INCLUDEALL+5, DoMainMenuIncludeSet,
IDM_INCLUDEALL+6, DoMainMenuIncludeSet,
IDM_INCLUDEALL+7, DoMainMenuIncludeSet,
IDM_ABOUT, DoMainMenuAbout,
};
HANDLE hInst;
HWND hMain;
UINT wVersion = 10;
BOOL fFirst = TRUE;
char szAppName[] = "WinThinDisk"; // Application name
char szTitleText[] = "ThinDisk"; // Application window title
char szMenuName[] = "WinThinDiskMenu"; // Menu name
char szIconName[] = "WinThinDiskIcon"; // Icon name
char szProfileName[] = "ThinDisk.ini"; // INI file name
FARPROC lpfnOldLBoxWndProc; //Old Listbox procedure
BOOL fFindNew = TRUE; //First time Find pressed flag
BOOL fSelOS = FALSE; //Some selected Listbox items not visible
INT sOldIncCnt = 1; //Flag used to regen include set menu
UINT fViewFlags = 0x0f; //Default view set flags
//
//Virtual List box stuff
//
INT sListSize;
INT sLItemHeight = 1;
//
// Global pointers used in recursive directory scan
//
BOOL fSearching = FALSE;
LPLPMYDIRENTRY lpIndexPtr;
LPLPMYDIRENTRY lpDestPtr;
char szSearchDir[MAXFNAMELEN] = "";
char szStatText[80] = "";
char *pszStatEnd;
//
// Directory entry block items
//
LPMYDIRENTRY lpDirEntry;
LPBUFFHDR lpCurrBuff;
BUFFHDR Buff = {0,0,0};
INT sMasterCount = 0;
UINT usLevel;
UINT usItteration, usGoal, usLastStat;
//
// Include array stuff
//
INT sCount = 0, sDirCnt = 0;
INT sIncCount;
INCSPEC incArray[MAXINCSPECS];
LPINCSPEC lpCurrInc;
//
// Sorting arrays
//
BOOL fSortUp = FALSE;
UINT hMasterSeg = 0;
INT sSortIndex = 0;
UINT hSortSeg[SORTTYPES] = {0,0,0,0};
SORTFUNC pSortFunc[SORTTYPES] = {SortName, SortExt, SortSize, SortDate};
char *szSortLabel[SORTTYPES] = {"name", "extension", "size", "date"};
//File functions
FILEFUNC pFileFunc[FUNCTYPES] = {CopyFile, MoveFile, DeleteFile};
//============================================================
// WinMain -- entry point for this application from Windows.
//============================================================
INT APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpCmdLine, INT nCmdShow) {
MSG msg;
INT rc;
HANDLE hAccel;
hInst = hInstance;
//
// If first instance, perform any init processing
//
if(!hPrevInstance)
if((rc = InitApp(hInstance)) != 0)
return rc;
//
// Initialize this instance
//
if((rc = InitInstance(hInstance, lpCmdLine, nCmdShow)) != 0)
return rc;
//
// Application message loop
//
hAccel = LoadAccelerators (hInstance, szAppName);
while (GetMessage (&msg, NULL, 0, 0)) {
if (!TranslateAccelerator (hMain, hAccel, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Instance cleanup
return TermInstance(hInstance, msg.wParam);
}
//-----------------------------------------------------------
// InitApp - Global initialization code for this application.
//-----------------------------------------------------------
INT InitApp(HANDLE hInstance) {
WNDCLASS wc;
//
// Register App Main Window class
//
wc.style = 0; // Window style
wc.lpfnWndProc = MainWndProc; // Callback function
wc.cbClsExtra = 0; // Extra class data
wc.cbWndExtra = 0; // Extra window data
wc.hInstance = hInstance; // Owner handle
wc.hIcon = LoadIcon(hInst, szIconName); // Application icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Default cursor
wc.hbrBackground = COLOR_WINDOW + 1;
wc.lpszMenuName = szMenuName; // Menu name
wc.lpszClassName = szAppName; // Window class name
if (RegisterClass(&wc) == 0)
return 1;
StatusBarInit (hInstance);
return 0;
}
//-----------------------------------------------------------
// InitInstance - Instance initialization code for this app.
//-----------------------------------------------------------
INT InitInstance(HANDLE hInstance, LPSTR lpCmdLine, INT nCmdShow) {
INT x,y, cx, cy;
HDC hdc;
TEXTMETRIC tm;
INT sField[4];
char szIn[40], szTemp[33];
//
//Determine the size of the system font to set the sizes of the
//window controls.
//
hdc = GetDC (NULL);
SelectObject (hdc, GetStockObject (SYSTEM_FONT));
GetTextMetrics (hdc, &tm);
sLItemHeight = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC (NULL, hdc);
//Read INI file info
x = GetPrivateProfileInt (szAppName, PRO_XPOS, CW_USEDEFAULT,
szProfileName);
y = GetPrivateProfileInt (szAppName, PRO_YPOS, CW_USEDEFAULT,
szProfileName);
cx = GetPrivateProfileInt (szAppName, PRO_XSIZE, CW_USEDEFAULT,
szProfileName);
cy = GetPrivateProfileInt (szAppName, PRO_YSIZE, CW_USEDEFAULT,
szProfileName);
//Setup initial include array
lpCurrInc = &incArray[0];
sIncCount = GetPrivateProfileInt (szAppName, PRO_INCCNT, 0, szProfileName);
if (sIncCount) {
for (x = 0; x < sIncCount; x++) {
itoa (x, szIn, 10);
GetPrivateProfileString (szIn, PRO_SPECNAME, "Inc Spec",
lpCurrInc->szSpecName,
sizeof (lpCurrInc->szSpecName), szProfileName);
GetPrivateProfileString (szIn, PRO_FILESPEC, "*.*", lpCurrInc->szFileSpec,
sizeof (lpCurrInc->szFileSpec), szProfileName);
GetPrivateProfileString (szIn, PRO_INCSIZE, "0", szTemp,
sizeof (szTemp), szProfileName);
lpCurrInc->lIncSize = atol (szTemp);
lpCurrInc->usIncDate = GetPrivateProfileInt (szIn, PRO_INCDATE,
0x21, szProfileName);
lpCurrInc->usIncFlags = GetPrivateProfileInt (szIn, PRO_INCFLAGS,
_A_RDONLY | _A_ARCH | _A_HIDDEN | _A_SYSTEM,
szProfileName);
lpCurrInc->fScrnFlags = GetPrivateProfileInt (szIn, PRO_SCRNFLAGS,
SCRN_INCEMPTYDIRS, szProfileName);
lpCurrInc++;
}
lpCurrInc = &incArray[0];
} else {
sIncCount = 1;
memset (&incArray[0], 0, sizeof (INCSPEC));
lstrcpy (lpCurrInc->szSpecName, "All Files");
lstrcpy (lpCurrInc->szFileSpec, "*.*");
lpCurrInc->usIncFlags = _A_RDONLY | _A_ARCH | _A_HIDDEN | _A_SYSTEM;
lpCurrInc->fScrnFlags = SCRN_INCEMPTYDIRS;
}
// Create main window
hMain = CreateWindow (szAppName, szTitleText, WS_OVERLAPPEDWINDOW,
x, y, cx, cy, NULL, NULL, hInstance, NULL);
if(!hMain) return 0x10;
//Create status bar
sField[0] = 0;
sField[1] = 195;
x = StatusBarCreate (hMain, 2, sField);
if (x) return x;
ShowWindow(hMain, nCmdShow | SW_SHOW);
UpdateWindow(hMain); // force WM_PAINT message
return 0; // return success flag
}
//------------------------------------------------------------
// TermInstance - Instance termination code for this app.
//------------------------------------------------------------
INT TermInstance(HANDLE hinstance, int sDefRC) {
INT i;
if (hMasterSeg)
GlobalFree (hMasterSeg);
for (i = 0; i < SORTTYPES; i++)
if (hSortSeg[i])
GlobalFree (hSortSeg[i]);
return sDefRC;
}
//============================================================
// Message handling procedures for MainWindow
//============================================================
//------------------------------------------------------------
// MainWndProc - Callback function for application window
//------------------------------------------------------------
LONG CALLBACK MainWndProc(HWND hWnd, UINT wMsg, UINT wParam,
LONG lParam) {
INT i;
//
// Search message list to see if we need to handle this
// message. If in list, call procedure.
//
for(i = 0; i < dim(MainMessages); i++) {
if(wMsg == MainMessages[i].Code)
return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
}
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
//------------------------------------------------------------
// DoCreateMain - process WM_CREATE message for frame window.
//------------------------------------------------------------
LONG DoCreateMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
RECT rect;
HWND hWndLB;
GetFListPos (hWnd, &rect);
hWndLB = CreateWindow ("listbox", NULL, WS_CHILD | WS_VISIBLE |
WS_BORDER | LBS_NOTIFY | LBS_OWNERDRAWFIXED |
LBS_MULTIPLESEL | LBS_EXTENDEDSEL,
rect.left, rect.top, rect.right, rect.bottom,
hWnd, IDD_FLIST, hInst, NULL);
//Subclass listbox to virtualize large box.
lpfnOldLBoxWndProc = MySubClassWindow (GetDlgItem (hWnd, IDD_FLIST),
MakeProcInstance ((FARPROC) LBoxSCProc, hInst));
SetWindowLong (hWndLB, GWL_STYLE,
GetWindowLong (hWndLB, GWL_STYLE) | WS_VSCROLL);
SetScrollPos (GetDlgItem (hWnd, IDD_FLIST), SB_VERT, 0, TRUE);
return 0;
}
//------------------------------------------------------------
// DoSizeMain - process WM_SIZE message for frame window.
//------------------------------------------------------------
LONG DoSizeMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
RECT rect, rectList;
INT sTop;
if (wParam != SIZE_MINIMIZED) {
GetFListPos (hWnd, &rect);
SetWindowPos (GetDlgItem (hWnd, IDD_FLIST), NULL, rect.left, rect.top,
rect.right, rect.bottom, SWP_NOZORDER);
// Get size of listbox to determine the number of items visible
// in the list box.
GetClientRect (GetDlgItem (hWnd, IDD_FLIST), &rectList);
if (sLItemHeight)
sListSize = (rectList.bottom - rectList.top)/sLItemHeight;
sTop = (INT) SendDlgItemMessage (hWnd, IDD_FLIST, LB_GETITEMDATA, 0, 0);
if ((UINT) sTop > (UINT) sCount)
sTop = 0;
FillLB (hWnd, sTop);
DisplayCurrStatus (hWnd);
if (fFirst) {
fFirst = FALSE;
PostMessage (hWnd, WM_COMMAND, IDM_REFRESH, 0);
}
}
return 0;
}
//------------------------------------------------------------
// DoSetFocusMain - process WM_SETFOCUS message for frame window.
//------------------------------------------------------------
LONG DoSetFocusMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
SetFocus (GetDlgItem (hWnd, IDD_FLIST));
return 0;
}
//------------------------------------------------------------
// DoMeasureItemMain - process WM_MEASUREITEM message for frame window.
//------------------------------------------------------------
LONG DoMeasureItemMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
((LPMEASUREITEMSTRUCT) lParam)->itemHeight = sLItemHeight;
return 0;
}
//------------------------------------------------------------
// DoDrawItemMain - process WM_DRAWITEM message for frame
// window. This routine handles drawing of the list box
// items.
//------------------------------------------------------------
LONG DoDrawItemMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
LPDRAWITEMSTRUCT lpdiPtr;
LPMYDIRENTRY lpDrawEnt;
LPLPMYDIRENTRY lpIndexPtr;
char szOut[256], szTemp[33];
char *pszOut;
RECT rectOut;
HANDLE hBrush;
INT i, sNumLen;
HPEN hPen, hOldPen;
if (fSearching)
return FALSE;
if (hSortSeg[sSortIndex] == 0)
return FALSE;
lpdiPtr = (LPDRAWITEMSTRUCT) lParam;
if ((UINT)lpdiPtr->itemData > (UINT)sCount)
return 0;
if (lpdiPtr->itemState & ODS_SELECTED) {
SetTextColor (lpdiPtr->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
SetBkColor (lpdiPtr->hDC, GetSysColor (COLOR_HIGHLIGHT));
hBrush = CreateSolidBrush (GetSysColor (COLOR_HIGHLIGHT));
} else {
SetTextColor (lpdiPtr->hDC, GetSysColor (COLOR_WINDOWTEXT));
SetBkColor (lpdiPtr->hDC, GetSysColor (COLOR_WINDOW));
hBrush = CreateSolidBrush (GetSysColor (COLOR_WINDOW));
}
rectOut = lpdiPtr->rcItem;
FillRect (lpdiPtr->hDC, &rectOut, hBrush);
DeleteObject (hBrush);
rectOut.right = lpdiPtr->rcItem.left + 135;
rectOut.bottom = lpdiPtr->rcItem.bottom;
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
lpIndexPtr += (INT)lpdiPtr->itemData;
lpDrawEnt = *lpIndexPtr;
// Display file name
if (lpDrawEnt->ucAttrib & _A_SUBDIR) {
szOut[0] = '[';
lstrcpy (&szOut[1], lpDrawEnt->szName);
strcat (szOut, "]");
} else
lstrcpy (szOut, lpDrawEnt->szName);
pszOut = szOut;
while (*pszOut == ' ')
pszOut++;
DrawText (lpdiPtr->hDC, pszOut, -1, &rectOut, DT_LEFT | DT_SINGLELINE);
// Display file size
if (fViewFlags & SHOW_SIZE) {
ltoa (lpDrawEnt->lSize, szTemp, 10);
sNumLen = strlen (szTemp);
pszOut = szOut;
for (i = 0; i < sNumLen; i++) {
if ((sNumLen - i) % 3 == 0 && i != 0)
*pszOut++ = ',';
*pszOut++ = szTemp[i];
}
*pszOut = '\0';
rectOut.left = rectOut.right;
rectOut.right += 90;
DrawText (lpdiPtr->hDC, szOut, -1, &rectOut, DT_RIGHT | DT_SINGLELINE);
rectOut.right += 15;
}
// Display date
if (fViewFlags & SHOW_DATE) {
rectOut.left = rectOut.right;
rectOut.right += 160;
Date2asc (lpDrawEnt->usDate, lpDrawEnt->usTime, szOut);
DrawText (lpdiPtr->hDC, szOut, -1, &rectOut, DT_LEFT | DT_SINGLELINE);
}
// Display attributes
if (fViewFlags & SHOW_ATTRIB) {
rectOut.left = rectOut.right;
rectOut.right += 50;
Attr2asc (lpDrawEnt->ucAttrib, szOut);
DrawText (lpdiPtr->hDC, szOut, -1, &rectOut, DT_LEFT | DT_SINGLELINE);
}
// Display complete path
if (fViewFlags & SHOW_PATH) {
if (lpDrawEnt->lpParent) {
i = sizeof (szOut);
szOut[0] = '\0';
CreatePath (lpDrawEnt, szOut, &i);
} else {
lstrcpy (szOut, lpDrawEnt->szName);
}
rectOut.left = rectOut.right;
rectOut.right += 500;
pszOut = szOut;
while (*pszOut == ' ')
pszOut++;
DrawText (lpdiPtr->hDC, pszOut, -1, &rectOut, DT_LEFT | DT_SINGLELINE);
}
GlobalUnlock (hSortSeg[sSortIndex]);
if (lpdiPtr->itemState & ODS_FOCUS) {
if (lpdiPtr->itemState & ODS_SELECTED)
hPen = CreatePen (PS_DOT, 1, GetSysColor (COLOR_HIGHLIGHTTEXT));
else
hPen = CreatePen (PS_DOT, 1, GetSysColor (COLOR_WINDOWTEXT));
hOldPen = SelectObject (lpdiPtr->hDC, hPen);
MoveTo (lpdiPtr->hDC, lpdiPtr->rcItem.left, lpdiPtr->rcItem.bottom-1);
LineTo (lpdiPtr->hDC, lpdiPtr->rcItem.left, lpdiPtr->rcItem.top);
LineTo (lpdiPtr->hDC, lpdiPtr->rcItem.right-1, lpdiPtr->rcItem.top);
LineTo (lpdiPtr->hDC, lpdiPtr->rcItem.right-1, lpdiPtr->rcItem.bottom-1);
LineTo (lpdiPtr->hDC, lpdiPtr->rcItem.left, lpdiPtr->rcItem.bottom-1);
SelectObject (lpdiPtr->hDC, hOldPen);
DeleteObject (hPen);
}
return 0;
}
//------------------------------------------------------------
// DoInitMenuMain - process WM_INITMENU message for frame window.
//------------------------------------------------------------
LONG DoInitMenuMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
INT i;
HMENU hMenu;
//Check menu item of active sort type
for (i = 0; i < SORTTYPES; i++)
if (i == sSortIndex)
CheckMenuItem ((HMENU) wParam, IDM_SORTNAME + i, MF_BYCOMMAND | MF_CHECKED);
else
CheckMenuItem ((HMENU) wParam, IDM_SORTNAME + i, MF_BYCOMMAND | MF_UNCHECKED);
//Check the viewing selection items size, date, attrib and path
if (fViewFlags & SHOW_SIZE)
CheckMenuItem ((HMENU) wParam, IDM_SHOWSIZE, MF_BYCOMMAND | MF_CHECKED);
else
CheckMenuItem ((HMENU) wParam, IDM_SHOWSIZE, MF_BYCOMMAND | MF_UNCHECKED);
if (fViewFlags & SHOW_DATE)
CheckMenuItem ((HMENU) wParam, IDM_SHOWDATE, MF_BYCOMMAND | MF_CHECKED);
else
CheckMenuItem ((HMENU) wParam, IDM_SHOWDATE, MF_BYCOMMAND | MF_UNCHECKED);
if (fViewFlags & SHOW_ATTRIB)
CheckMenuItem ((HMENU) wParam, IDM_SHOWATTRIB, MF_BYCOMMAND | MF_CHECKED);
else
CheckMenuItem ((HMENU) wParam, IDM_SHOWATTRIB, MF_BYCOMMAND | MF_UNCHECKED);
if (fViewFlags & SHOW_PATH)
CheckMenuItem ((HMENU) wParam, IDM_SHOWPATH, MF_BYCOMMAND | MF_CHECKED);
else
CheckMenuItem ((HMENU) wParam, IDM_SHOWPATH, MF_BYCOMMAND | MF_UNCHECKED);
//Get menu for include set
if (sOldIncCnt != sIncCount) {
hMenu = GetSubMenu (GetMenu (hWnd), MENU_INCLUDE);
for (i = 1; i < 8; i++)
if (!DeleteMenu (hMenu, IDM_INCLUDEALL + i, MF_BYCOMMAND))
break;
for (i = 1; i < sIncCount; i++)
AppendMenu (hMenu, MF_ENABLED, IDM_INCLUDEALL + i,
incArray[i].szSpecName);
sOldIncCnt = sIncCount;
}
return 0;
}
//------------------------------------------------------------
// DoCommandMain - process WM_COMMAND message for frame window
// by decoding the menubar item with the menuitems[] array,
// then running the corresponding function to process the command.
//------------------------------------------------------------
LONG DoCommandMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
INT i;
UINT idItem, wNotifyCode;
HWND hwndCtl;
idItem = (UINT) wParam; // Parse Parameters
hwndCtl = (HWND) LOWORD(lParam);
wNotifyCode = (UINT) HIWORD(lParam);
//
// Call routine to handle control message
//
for(i = 0; i < dim(MainMenuItems); i++) {
if(idItem == MainMenuItems[i].Code)
return (*MainMenuItems[i].Fxn)(hWnd, idItem, hwndCtl,
wNotifyCode);
}
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
//------------------------------------------------------------
// DoCloseMain - process WM_CLOSE message for frame window.
//------------------------------------------------------------
LONG DoCloseMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
fSearching = FALSE;
DestroyWindow (hMain);
return 0;
}
//------------------------------------------------------------
// DoDestroyMain - process WM_DESTROY message for frame window.
//------------------------------------------------------------
LONG DoDestroyMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
RECT rect;
char szOut[40], szTemp[33];
INT i;
fSearching = FALSE;
//Save Window position
if (!IsIconic (hWnd) && !IsZoomed (hWnd)) {
GetWindowRect (hWnd, &rect);
MyWritePrivateProfileInt (szAppName, PRO_XPOS, rect.left,
10, szProfileName);
MyWritePrivateProfileInt (szAppName, PRO_YPOS, rect.top,
10, szProfileName);
MyWritePrivateProfileInt (szAppName, PRO_XSIZE, rect.right - rect.left,
10, szProfileName);
MyWritePrivateProfileInt (szAppName, PRO_YSIZE, rect.bottom - rect.top,
10, szProfileName);
}
//
//Write include array info
//
for (i = 1; i < MAXINCSPECS; i++) {
itoa (i, szOut, 10);
//Erase entry
WritePrivateProfileString (szOut, "", "", szProfileName);
}
lpCurrInc = &incArray[0];
MyWritePrivateProfileInt (szAppName, PRO_INCCNT, sIncCount, 10, szProfileName);
for (i = 0; i < sIncCount; i++) {
itoa (i, szOut, 10);
WritePrivateProfileString (szOut, PRO_SPECNAME, lpCurrInc->szSpecName,
szProfileName);
WritePrivateProfileString (szOut, PRO_FILESPEC, lpCurrInc->szFileSpec,
szProfileName);
ltoa (lpCurrInc->lIncSize, szTemp, 10);
WritePrivateProfileString (szOut, PRO_INCSIZE, szTemp, szProfileName);
MyWritePrivateProfileInt (szOut, PRO_INCDATE, lpCurrInc->usIncDate,
10, szProfileName);
MyWritePrivateProfileInt (szOut, PRO_INCFLAGS, lpCurrInc->usIncFlags,
10, szProfileName);
MyWritePrivateProfileInt (szOut, PRO_SCRNFLAGS, lpCurrInc->fScrnFlags,
10, szProfileName);
lpCurrInc++;
}
//Remove subclassing on listbox
MySubClassWindow (GetDlgItem (hWnd, IDD_FLIST), lpfnOldLBoxWndProc);
PostQuitMessage (0);
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
//============================================================
// Control handling procedures for MainWindow
//============================================================
//------------------------------------------------------------
// DoMainCtlFList - Process Listbox control messages
//------------------------------------------------------------
LONG DoMainCtlFList (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
INT i, sSelCnt;
LPLPMYDIRENTRY lpIndexPtr;
if (wNotifyCode == LBN_SELCHANGE) {
sSelCnt = (INT) SendDlgItemMessage (hWnd, IDD_FLIST, LB_GETSELCOUNT,
0, 0);
if ((sSelCnt <= 1) && fSelOS) {
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
for (i = 0; i < sCount; i++) {
(*lpIndexPtr)->ucAttrib &= ~ATTR_SELECTED;
lpIndexPtr++;
}
fSelOS = FALSE;
GlobalUnlock (hSortSeg[sSortIndex]);
}
}
return 0;
}
//------------------------------------------------------------
// DoMainMenuRefresh - Process Refresh menu item
//------------------------------------------------------------
LONG DoMainMenuRefresh (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
INT rc;
MyDisplayDialog(hInst, "Refresh", hWnd,
(WNDPROC) RefreshDlgProc, 0);
rc = GetIncludedFiles (hWnd);
if (rc)
PrintError (hWnd, rc);
else {
FillLB (hWnd, 0);
DisplayCurrStatus (hWnd);
}
return 0;
}
//------------------------------------------------------------
// DoMainMenuMCD - Process Move, Copy and Delete menu items
//------------------------------------------------------------
LONG DoMainMenuMCD (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
INT rc;
if ((SendDlgItemMessage (hWnd, IDD_FLIST, LB_GETSELCOUNT, 0, 0) == 0) && !fSelOS) {
MessageBox (hWnd, "No files selected.",
szTitleText, MB_OK | MB_ICONHAND);
return 0;
}
if (idItem == IDM_DELETE)
rc = MyDisplayDialog(hInst, "DelFiles", hWnd, (WNDPROC) MoveCopyDelDlgProc,
(DWORD)idItem - IDM_COPY);
else
rc = MyDisplayDialog(hInst, "MoveCopyFiles", hWnd,
(WNDPROC) MoveCopyDelDlgProc, (DWORD)idItem - IDM_COPY);
if (rc == 0) {
rc = GetIncludedFiles (hWnd);
if (rc) {
PrintError (hWnd, rc);
return 0;
}
FillLB (hWnd, 0);
}
DisplayCurrStatus (hWnd);
return 0;
}
//------------------------------------------------------------
// DoMainMenuExit - Process Exit menu item
//------------------------------------------------------------
LONG DoMainMenuExit (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
SendMessage (hWnd, WM_CLOSE, 0, 0);
return 0;
}
//------------------------------------------------------------
// DoMainMenuFind - Process Find, Find Next and Find Prev menu items.
//------------------------------------------------------------
LONG DoMainMenuFind (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
static INCSPEC incData;
LPLPMYDIRENTRY lpIndexPtr;
INT sStart, i;
BOOL fFound = FALSE;
if ((idItem == IDM_FIND) || fFindNew) {
memset (&incData, 0, sizeof (incData));
lstrcpy (incData.szFileSpec, "*.*");
incData.usIncDate = 0x21;
incData.fScrnFlags = 1 | DLG_FIND;
i = MyDisplayDialog(hInst, "FindFile", hWnd, (WNDPROC) IncFilesDlgProc,
(DWORD)(LPVOID)&incData);
if (i == 0)
return 0;
}
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
if (lpIndexPtr == 0)
return 0;
sStart = (INT) SendDlgItemMessage (hWnd, IDD_FLIST, LB_GETCARETINDEX, 0, 0);
if (sStart == LB_ERR)
sStart = 0;
sStart = (INT) SendDlgItemMessage (hWnd, IDD_FLIST, LB_GETITEMDATA,
sStart, 0);
if (idItem == IDM_FINDPREV) {
for (i = max (sStart-1, 0); (i >= 0) && !fFound; i--) {
fFound = ScreenFile (*(lpIndexPtr + i), &incData);
}
i++;
} else {
for (i = sStart; (i < sCount) && !fFound; i++) {
fFound = ScreenFile (*(lpIndexPtr + i), &incData);
if ((fFound) && (i == sStart) && !fFindNew)
fFound = FALSE;
}
i--;
}
if (fFound) {
i = max (i - 3, 0);
FillLB (hWnd, i);
SendDlgItemMessage (hWnd, IDD_FLIST, LB_SETSEL, TRUE, min (3, i));
SetStatusBarText (hWnd, "File Found", 0);
} else
SetStatusBarText (hWnd, "No Files Found", 0);
GlobalUnlock (hSortSeg[sSortIndex]);
fFindNew = FALSE;
return 0;
}
//------------------------------------------------------------
// DoMainMenuInvert - Process Sort Assending/descending menu
// items.
//------------------------------------------------------------
LONG DoMainMenuInvert (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
HMENU hMenu;
INT i;
hMenu = GetSubMenu (GetMenu (hWnd), MENU_VIEW);
if (fSortUp)
fSortUp = FALSE;
else
fSortUp = TRUE;
// Invert the index arrays
if (!hMasterSeg)
return 0;
for (i = 0; i < SORTTYPES; i++)
if (hSortSeg[i]) {
InvertIndex ((HPDWORD)GlobalLock (hSortSeg[i]), sCount);
GlobalUnlock (hSortSeg[i]);
}
FillLB (hWnd, 0);
DisplayCurrStatus (hWnd);
return 0;
}
//------------------------------------------------------------
// DoMainMenuShow - Process Show Attrib, Show Size ect. menu
// items.
//------------------------------------------------------------
LONG DoMainMenuShow (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
UINT usIndex;
HMENU hMenu;
hMenu = GetSubMenu (GetMenu (hWnd), MENU_VIEW);
usIndex = idItem - IDM_SHOWSIZE;
if (GetMenuState (hMenu, idItem, MF_BYCOMMAND) == MF_CHECKED)
fViewFlags &= ~(1 << usIndex);
else
fViewFlags |= (1 << usIndex);
InvalidateRect (hWnd, NULL, FALSE);
return 0;
}
//------------------------------------------------------------
// DoMainMenuSort - Process Sort by... menu items.
//------------------------------------------------------------
LONG DoMainMenuSort (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
INT i, sIndex, rc;
HPDWORD lpDest, lpSrc;
LPLPMYDIRENTRY lpIndexPtr;
sIndex = idItem - IDM_SORTNAME;
if (sCount == 0)
return 0;
if (hSortSeg[sIndex] == 0) {
hSortSeg[sIndex] = GlobalAlloc (GHND, (LONG)sCount * sizeof (LPMYDIRENTRY));
if (hSortSeg[sIndex] == 0) {
PrintError (hWnd, ERR_OUTOFMEM);
return 0;
}
SetStatusBarText (hWnd, "Sorting...", 0);
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sIndex]);
lpDest = (HPDWORD) lpIndexPtr;
lpSrc = (HPDWORD) GlobalLock (hSortSeg[sSortIndex]);
for (i = 0; i < sCount; i++)
*lpDest++ = *lpSrc++;
GlobalUnlock (hSortSeg[sSortIndex]);
rc = MyQSort (lpIndexPtr, sCount, (PSORTFUNC) pSortFunc[sIndex]);
if (rc)
PrintError (hWnd, rc);
DisplayCurrStatus (hWnd);
GlobalUnlock (hSortSeg[sIndex]);
}
FillLB (hWnd, 0);
sSortIndex = sIndex;
DisplayCurrStatus (hWnd);
InvalidateRect (hWnd, NULL, FALSE);
return 0;
}
//------------------------------------------------------------
// DoMainMenuInclude - Process Include|Define Include Set menu item
//------------------------------------------------------------
LONG DoMainMenuInclude (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
INCSPEC incData;
memset (&incData, 0, sizeof (incData));
lstrcpy (incData.szFileSpec, "*.*");
incData.usIncFlags = _A_RDONLY | _A_ARCH | _A_HIDDEN | _A_SYSTEM;
incData.usIncDate = 0x21;
incData.fScrnFlags = 1 | DLG_INCLUDE;
if (MyDisplayDialog(hInst, "IncFiles", hWnd,
(WNDPROC) IncFilesDlgProc, (DWORD)(LPVOID)&incData)) {
incData.fScrnFlags &= ~DLG_INCLUDE;
AddIncSet (hWnd, &incData);
}
return 0;
}
//------------------------------------------------------------
// DoMainMenuIncludeEdit - Process Include|Edit Include Set menu item
//------------------------------------------------------------
LONG DoMainMenuIncludeEdit (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
INCSPEC incData;
INT rc, sEditItem;
BOOL fReset = FALSE;
if (sIncCount <= 1) {
MessageBox (hWnd, "The \'All Files\' Query can not be edited.",
szTitleText, MB_OK | MB_ICONHAND);
return 0;
}
sEditItem = MyDisplayDialog(hInst, "IncludeDel", hWnd,
(WNDPROC) IncludeDelDlgProc, 1);
if (sEditItem == 0)
return 0;
incData = incArray[sEditItem];
incData.fScrnFlags |= DLG_INCLUDEEDIT;
rc = MyDisplayDialog (hInst, "IncFiles", hWnd, (WNDPROC)IncFilesDlgProc,
(DWORD)(LPVOID)&incData);
if (rc == 0)
return 0;
incData.fScrnFlags &= ~DLG_INCLUDEEDIT;
sOldIncCnt = 0; //Force menu regen on next menu init.
if (rc == 2)
AddIncSet (hWnd, &incData);
else {
incArray[sEditItem] = incData;
lpCurrInc = &incArray[sEditItem];
rc = GetIncludedFiles (hWnd);
if (rc) {
PrintError (hWnd, rc);
return 0;
}
FillLB (hWnd, 0);
DisplayCurrStatus (hWnd);
}
return 0;
}
//------------------------------------------------------------
// DoMainMenuIncludeDel - Process Include|Del Include Set menu item
//------------------------------------------------------------
LONG DoMainMenuIncludeDel (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
INT i, rc, sDelItem;
BOOL fReset = FALSE;
if (sIncCount <= 1) {
MessageBox (hWnd, "The \'All Files\' Query can not be deleted.",
szTitleText, MB_OK | MB_ICONHAND);
return 0;
}
sDelItem = MyDisplayDialog(hInst, "IncludeDel", hWnd,
(WNDPROC) IncludeDelDlgProc, 0);
if (sDelItem == 0)
return 0;
// If deleting current inc set, make all files current set
if (lpCurrInc == &incArray[sDelItem]) {
lpCurrInc = incArray;
fReset = TRUE;
} else if (lpCurrInc > &incArray[sDelItem])
lpCurrInc--;
//Delete item by overwriting others on top of it.
for (i = sDelItem; i < sIncCount; i++)
incArray[i] = incArray[i+1];
sIncCount--;
if (fReset) {
rc = GetIncludedFiles (hWnd);
if (rc) {
PrintError (hWnd, rc);
return 0;
}
FillLB (hWnd, 0);
DisplayCurrStatus (hWnd);
}
return 0;
}
//------------------------------------------------------------
// DoMainMenuIncludeSet - Process Include set menu items
//------------------------------------------------------------
LONG DoMainMenuIncludeSet (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
UINT i;
INT rc;
i = idItem - IDM_INCLUDEALL;
lpCurrInc = &incArray[i];
//Get include set
rc = GetIncludedFiles (hWnd);
if (rc) {
PrintError (hWnd, rc);
return 0;
}
FillLB (hWnd, 0);
DisplayCurrStatus (hWnd);
return 0;
}
//------------------------------------------------------------
// DoMainMenuAbout - Process About button
//------------------------------------------------------------
LONG DoMainMenuAbout (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
MyDisplayDialog(hInst, "AboutBox", hWnd,
(WNDPROC) AboutDlgProc, (LONG) wVersion);
return 0;
}
//============================================================
// Virtual list box routines
//
// The virtual list box designed here is incomplete, since
// it depends on the index to store its data pointer
// and on the file data structures to store the a
// 'selected flag' for an item when it is not displayed
// in the listbox. Also, such niceties as the
// LBS_WANTKEYBOARDINPUT style are not supported.
//============================================================
//------------------------------------------------------------
// ScrollVLBDown - Scroll the virtual list box down one item
//------------------------------------------------------------
INT ScrollVLBDown (HWND hWnd, INT sSCnt, BOOL fSelected) {
INT i, sIndex, sIndexBot;
LPLPMYDIRENTRY lpIndexPtr;
LPMYDIRENTRY lpEntry;
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
for (i = 0; i < sSCnt; i++) {
//If at end of list, return
//Check item about to be scrolled off the top of the list.
//If selected, mark.
sIndexBot = (INT) SendMessage (hWnd, LB_GETITEMDATA, sListSize-1, 0);
sIndex = (INT) SendMessage (hWnd, LB_GETITEMDATA, 0, 0);
if ((sIndexBot == LB_ERR) || (sIndexBot >= sCount - 1) || (sIndex == LB_ERR))
break;
lpEntry = *(lpIndexPtr + sIndex);
if (SendMessage (hWnd, LB_GETSEL, 0, 0)) {
lpEntry->ucAttrib |= ATTR_SELECTED;
fSelOS = TRUE;
} else
lpEntry->ucAttrib &= ~ATTR_SELECTED;
//Turn off redraw add new item at bottom, delete top item
SendMessage (hWnd, LB_DELETESTRING, 0, 0);
sIndex = (INT) SendMessage (hWnd, LB_INSERTSTRING, -1, sIndexBot+1);
lpEntry = *(lpIndexPtr + sIndexBot + 1);
if ((lpEntry->ucAttrib & ATTR_SELECTED) || fSelected)
SendMessage (hWnd, LB_SETSEL, TRUE, sIndex);
}
GlobalUnlock (hSortSeg[sSortIndex]);
return i;
}
//------------------------------------------------------------
// ScrollVLBUp - Scroll the virtual list box up one item
//------------------------------------------------------------
INT ScrollVLBUp (HWND hWnd, INT sSCnt, BOOL fSelected) {
INT i, sIndex, sIndexTop;
LPLPMYDIRENTRY lpIndexPtr;
LPMYDIRENTRY lpEntry;
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
for (i = 0; i < sSCnt; i++) {
//Check item about to be scrolled off the bottom of the list.
//If selected, mark.
sIndexTop = (INT) SendMessage (hWnd, LB_GETITEMDATA, 0, 0);
sIndex = (INT) SendMessage (hWnd, LB_GETITEMDATA, sListSize-1, 0);
if ((sIndexTop == LB_ERR) || (sIndexTop == 0))
break;
//Turn off redraw add new item at top, delete bottom item
if ((sIndex != LB_ERR) && (sIndex < sCount)) {
lpEntry = *(lpIndexPtr + sIndex);
if (SendMessage (hWnd, LB_GETSEL, sListSize-1, 0)) {
lpEntry->ucAttrib |= ATTR_SELECTED;
fSelOS = TRUE;
} else
lpEntry->ucAttrib &= ~ATTR_SELECTED;
SendMessage (hWnd, LB_DELETESTRING, sListSize-1, 0);
}
sIndex = (INT) SendMessage (hWnd, LB_INSERTSTRING, 0, sIndexTop - 1);
lpEntry = *(lpIndexPtr + sIndexTop - 1);
if ((lpEntry->ucAttrib & ATTR_SELECTED) || fSelected)
SendMessage (hWnd, LB_SETSEL, TRUE, sIndex);
SendMessage (hWnd, LB_SETTOPINDEX, 0, 0);
}
GlobalUnlock (hSortSeg[sSortIndex]);
return i;
}
//------------------------------------------------------------
// MoveVLB - Moves the top index of the listbox
//------------------------------------------------------------
INT MoveVLB (HWND hWnd, INT sPos) {
INT i, sIndex;
LPLPMYDIRENTRY lpIndexPtr;
LPMYDIRENTRY lpEntry;
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
SendMessage (hWnd, WM_SETREDRAW, FALSE, 0);
sIndex = (INT) SendMessage (hWnd, LB_GETITEMDATA, 0, 0);
if (sIndex == LB_ERR)
return 0;
for (i = 0; i < sListSize; i++) {
lpEntry = *(lpIndexPtr + sIndex + i);
if (SendMessage (hWnd, LB_GETSEL, i, 0)) {
lpEntry->ucAttrib |= ATTR_SELECTED;
fSelOS = TRUE;
} else
lpEntry->ucAttrib &= ~ATTR_SELECTED;
}
GlobalUnlock (hSortSeg[sSortIndex]);
SendMessage (hWnd, LB_RESETCONTENT, 0, 0);
for (i = sPos; (i < sPos + sListSize) && (i < sCount); i++) {
sIndex = (INT)SendMessage (hWnd, LB_ADDSTRING, 0, (LPARAM) (LONG) i);
lpEntry = *(lpIndexPtr + i);
if (lpEntry->ucAttrib & ATTR_SELECTED)
SendMessage (hWnd, LB_SETSEL, sIndex, 0);
}
SetScrollRange (hWnd, SB_VERT, 0, sCount - sListSize, FALSE);
SendMessage (hWnd, WM_SETREDRAW, TRUE, 0);
return 0;
}
//------------------------------------------------------------
// ClearSelVLB - Unselects all items.
//------------------------------------------------------------
void ClearSelVLB (HWND hWnd) {
INT i;
LPLPMYDIRENTRY lpIndexPtr;
SendMessage (hWnd, LB_SETSEL, FALSE, MAKELONG (-1, 0));
if (fSelOS) {
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
for (i = 0; i < sCount; i++) {
(*lpIndexPtr)->ucAttrib &= ~ATTR_SELECTED;
lpIndexPtr++;
}
fSelOS = FALSE;
GlobalUnlock (hSortSeg[sSortIndex]);
}
return;
}
//============================================================
// LBoxSCProc - Subclass procedure for Listbox
//============================================================
LONG CALLBACK LBoxSCProc (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
INT i, sScrollPos, sCaretIndex;
BOOL fShift;
switch (wMsg) {
case WM_VSCROLL:
sScrollPos = GetScrollPos (hWnd, SB_VERT);
switch (wParam) {
case SB_BOTTOM:
sScrollPos = sCount - sListSize;
break;
case SB_TOP:
sScrollPos = 0;
break;
case SB_LINEDOWN:
sScrollPos += ScrollVLBDown (hWnd, 1, FALSE);
break;
case SB_LINEUP:
sScrollPos -= ScrollVLBUp (hWnd, 1, FALSE);
break;
case SB_PAGEDOWN:
sScrollPos += ScrollVLBDown (hWnd, sListSize - 1, FALSE);
break;
case SB_PAGEUP:
sScrollPos -= ScrollVLBUp (hWnd, sListSize - 1, FALSE);
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
i = (INT) LOWORD (lParam) - sScrollPos;
if (i > sListSize)
MoveVLB (hWnd, LOWORD (lParam));
else if (i < 0)
sScrollPos -= ScrollVLBUp (hWnd, -i, FALSE);
else
sScrollPos += ScrollVLBDown (hWnd, i, FALSE);
sScrollPos = LOWORD (lParam);
break;
}
SetScrollPos (hWnd, SB_VERT, sScrollPos, TRUE);
return 0;
case WM_LBUTTONDOWN:
if (!(GetKeyState (VK_CONTROL) & 0x8000) &&
!(GetKeyState (VK_SHIFT) & 0x8000))
ClearSelVLB (hWnd);
break;
case WM_KEYDOWN:
sScrollPos = GetScrollPos (hWnd, SB_VERT);
sCaretIndex = (INT) SendMessage (hWnd, LB_GETCARETINDEX, 0, 0);
fShift = GetKeyState (VK_SHIFT) & 0x8000;
switch (wParam) {
case VK_END:
if (!fShift)
ClearSelVLB (hWnd);
FillLB (GetParent (hWnd), sCount - sListSize);
sCaretIndex = sListSize - 1;
sScrollPos = sCount - sListSize;
break;
case VK_HOME:
if (!fShift)
ClearSelVLB (hWnd);
FillLB (GetParent (hWnd), 0);
sCaretIndex = 0;
sScrollPos = 0;
break;
case VK_DOWN:
if (!fShift)
ClearSelVLB (hWnd);
if (sCaretIndex == sListSize - 1)
ScrollVLBDown (hWnd, 1, TRUE);
else
sCaretIndex++;
sScrollPos++;
break;
case VK_UP:
if (!fShift)
ClearSelVLB (hWnd);
if (sCaretIndex == 0)
ScrollVLBUp (hWnd, 1, TRUE);
else
sCaretIndex--;
sScrollPos--;
break;
case VK_NEXT:
if (!fShift)
ClearSelVLB (hWnd);
if (sCaretIndex > 0)
i = ScrollVLBDown (hWnd, sCaretIndex, fShift);
else
i = sListSize - 1;
sCaretIndex = sListSize - 1;
sScrollPos += i;
break;
case VK_PRIOR:
if (!fShift)
ClearSelVLB (hWnd);
if (sCaretIndex < sListSize - 1)
i = ScrollVLBUp (hWnd, sListSize - sCaretIndex - 1, fShift);
else
i = sListSize - 1;
sCaretIndex = 0;
sScrollPos -= i;
break;
default:
return CallWindowProc (lpfnOldLBoxWndProc, hWnd, wMsg,
wParam, lParam);
}
SendMessage (hWnd, LB_SETSEL, TRUE, sCaretIndex);
SendMessage (hWnd, LB_SETCARETINDEX, sCaretIndex, FALSE);
SetScrollPos (hWnd, SB_VERT, sScrollPos, TRUE);
return 0;
}
return CallWindowProc (lpfnOldLBoxWndProc, hWnd, wMsg,
wParam, lParam);
}
//============================================================
// RefreshDlgProc - Refresh dialog box dialog procedure
//============================================================
BOOL CALLBACK RefreshDlgProc (HWND hWnd, UINT wMsg, UINT wParam,
LONG lParam) {
INT sCnt, rc = 0, sDrives[26];
switch (wMsg) {
case WM_INITDIALOG:
SetStatusBarText (hMain, "Refresh file list", 0);
SendDlgItemMessage (hWnd, IDD_DRVLIST, LB_RESETCONTENT, 0, 0);
SendDlgItemMessage (hWnd, IDD_DRVLIST, LB_DIR,
DDL_DRIVES | DDL_EXCLUSIVE, (LONG)(LPSTR)"*.*");
return TRUE;
case WM_COMMAND:
switch (wParam) {
case IDD_REFRESH:
if (HIWORD(lParam) != BN_CLICKED)
return FALSE;
if (fSearching) {
fSearching = FALSE;
SetDlgItemText (hWnd, IDD_REFRESH, "Refresh");
} else {
sCnt = (INT) SendDlgItemMessage (hWnd, IDD_DRVLIST, LB_GETSELCOUNT, 0, 0);
if (sCnt == 0) {
MessageBox (hWnd, "No drives selected.", "ThinDisk",
MB_OK | MB_ICONASTERISK);
return 0;
}
SetDlgItemText (hWnd, IDD_REFRESH, "Stop");
SendDlgItemMessage (hWnd, IDD_DRVLIST, LB_GETSELITEMS, 26,
(LONG)(LPINT)sDrives);
SetStatusBarText (hMain, "Scanning drive(s)...", 0);
rc = ScanMachine (hWnd, sCnt, sDrives);
if (rc)
PrintError (hWnd, rc);
else
EndDialog(hWnd, 0);
}
fSearching = FALSE;
return TRUE;
case IDOK:
case IDCANCEL:
fSearching = FALSE;
EndDialog(hWnd, 0);
return TRUE;
}
}
return FALSE;
}
//============================================================
// MoveCopyDelDlgProc - Dialog procedure for Copy Move and Del
// dialog boxes.
//============================================================
BOOL CALLBACK MoveCopyDelDlgProc (HWND hWnd, UINT wMsg, UINT wParam,
LONG lParam) {
static INT sNum;
static HGLOBAL hBuff;
static INT sFuncType;
HGLOBAL hSet;
INT i, sIndex, sCnt, sTemp, rc;
LPLPMYDIRENTRY lpIndexPtr;
LPLPMYDIRENTRY lpSetPtr;
LPWORD lpArray;
char *pszDir;
char szFile[128];
char szDest[128];
switch (wMsg) {
case WM_INITDIALOG:
//Do Function specifc stuff
sFuncType = (INT) lParam;
if (sFuncType == 1) {
SetDlgItemText (hWnd, IDOK, "Move");
SetWindowText (hWnd, "Move Files");
SetWindowText (GetDlgItem (hWnd, IDD_COPYTEXT),
"The following files/directories are to be moved:");
}
//Init dlg controls
SendDlgItemMessage (hWnd, IDD_FILELIST, LB_RESETCONTENT, 0, 0);
SendDlgItemMessage (hWnd, IDD_FILELIST, LB_SETHORIZONTALEXTENT, 1000, 0);
//Get a list of all selected files and place in listbox
hBuff = GlobalAlloc (GHND, (LONG)sCount * sizeof (INT));
if (hBuff == 0)
return TRUE;
lpArray = (LPWORD) GlobalLock (hBuff);
sNum = (INT)SendMessage (GetDlgItem (hMain, IDD_FLIST),
LB_GETSELCOUNT, 0, 0);
SendMessage (GetDlgItem (hMain, IDD_FLIST), LB_GETSELITEMS, sNum,
(LONG)(LPWORD)lpArray);
for (i = 0; i < sNum; i++) {
*(lpArray + i) = (INT)SendMessage (
GetDlgItem (hMain, IDD_FLIST),
LB_GETITEMDATA, *(lpArray+i), 0L);
}
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
for (i = 0; i < sCount; i++) {
if (((*(lpIndexPtr + i))->ucAttrib & ATTR_SELECTED) &&
!((*(lpIndexPtr + i))->ucAttrib & ATTR_DELETED)) {
*(lpArray + sNum) = i;
sNum++;
}
}
for (i = 0; i < sNum; i++) {
sIndex = *(lpArray + i);
if (!((*(lpIndexPtr + sIndex))->ucAttrib & ATTR_DELETED)) {
if ((*(lpIndexPtr + sIndex))->ucAttrib & _A_SUBDIR)
strcpy (szFile, "Dir ");
else
strcpy (szFile, "File ");
sTemp = sizeof (szFile) - 5;
CreatePath (*(lpIndexPtr + sIndex), szFile+5, &sTemp);
SendDlgItemMessage (hWnd, IDD_FILELIST, LB_ADDSTRING, 0,
(LONG) (LPSTR) szFile);
}
}
GlobalUnlock (hBuff);
GlobalUnlock (hSortSeg[sSortIndex]);
return TRUE;
case WM_COMMAND:
switch (wParam) {
case IDOK:
//If move or copy, check out dest dir.
if (sFuncType < 2) {
OFSTRUCT of;
GetDlgItemText (hWnd, IDD_DESTPATH, szFile, sizeof (szFile));
_fullpath (szDest, szFile, sizeof (szDest));
OpenFile (szDest, &of, OF_EXIST);
if (of.nErrCode != 0) {
strcat (szDest, "\\COM");
OpenFile (szDest, &of, OF_EXIST);
szDest[strlen (szDest)-4] = '\0';
rc = 0;
if (of.nErrCode == 3)
rc = mkdir (szDest);
if (rc) {
MessageBox (hWnd,"Destination directory can\'t be created",
szTitleText, MB_OK | MB_ICONHAND);
return TRUE;
}
} else
if (sNum > 1) {
MessageBox (hWnd,
"Destination can\'t be a file when multiple files selected",
szTitleText, MB_OK | MB_ICONHAND);
return TRUE;
}
}
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
lpArray = (LPWORD) GlobalLock (hBuff);
//Get each selected item in list box
rc = 0;
for (i = 0; (i < sNum) && (rc == 0); i++) {
sIndex = *(lpArray + i);
if (!((*(lpIndexPtr + sIndex))->ucAttrib & ATTR_DELETED)) {
szFile[0] = '\0';
sTemp = sizeof (szFile);
CreatePath (*(lpIndexPtr + sIndex), szFile, &sTemp);
pszDir = szFile + strlen (szFile);
//If subdir, make call to get all files under the dir
if ((*(lpIndexPtr + sIndex))->ucAttrib & _A_SUBDIR) {
sCnt = 0;
hSet = GetIncludedSet (*(lpIndexPtr + sIndex), &sCnt);
if (hSet) {
lpSetPtr = (LPLPMYDIRENTRY) GlobalLock (hSet);
for (i = 0; (i < sCnt) && (rc == 0); i++) {
if (((*(lpSetPtr + i))->ucAttrib & _A_SUBDIR) == 0) {
sTemp = sizeof (szFile);
CreatePath (*(lpSetPtr + i), szFile, &sTemp);
rc = (pFileFunc[sFuncType])(*(lpSetPtr + i),
pszDir, szFile, szDest);
}
}
GlobalUnlock (hSet);
}
GlobalFree (hSet);
} else {
rc = (pFileFunc[sFuncType])(*(lpIndexPtr + sIndex),
pszDir, szFile, szDest);
}
}
}
if (rc)
PrintError (hWnd, rc);
GlobalUnlock (hSortSeg[sSortIndex]);
GlobalUnlock (hBuff);
GlobalFree (hBuff);
EndDialog(hWnd, rc);
return TRUE;
case IDCANCEL:
GlobalUnlock (hBuff);
GlobalFree (hBuff);
EndDialog(hWnd, ERR_CANCELED);
return TRUE;
}
}
return FALSE;
}
//============================================================
// IncFilesDlgProc - Include files dialog box dialog procedure
// This procedure is also used by the Find Dialog
//============================================================
BOOL CALLBACK IncFilesDlgProc (HWND hWnd, UINT wMsg, UINT wParam,
LONG lParam) {
static LPINCSPEC lpSpec;
char szTemp[40];
char *pszTemp;
INT i;
BOOL fFail;
UINT usDate;
switch (wMsg) {
case WM_INITDIALOG:
if (lParam == 0)
return FALSE;
lpSpec = (LPINCSPEC) lParam;
if ((lpSpec->fScrnFlags & DLG_INCLUDE) ||
(lpSpec->fScrnFlags & DLG_INCLUDEEDIT)) {
SendDlgItemMessage (hWnd, IDD_SPECNAME, EM_LIMITTEXT,
sizeof (lpSpec->szSpecName)-1, 0L);
SetDlgItemText (hWnd, IDD_SPECNAME, lpSpec->szSpecName);
}
SendDlgItemMessage (hWnd, IDD_FSPEC, EM_LIMITTEXT,
sizeof (lpSpec->szFileSpec)-1, 0L);
CheckDlgButton (hWnd, IDD_CHKFSPEC, lpSpec->fScrnFlags & SCRN_NAME);
SetDlgItemText (hWnd, IDD_FSPEC, lpSpec->szFileSpec);
CheckDlgButton (hWnd, IDD_CHKFSIZE, lpSpec->fScrnFlags & SCRN_SIZE);
ltoa (lpSpec->lIncSize, szTemp, 10);
SetDlgItemText (hWnd, IDD_FSIZE, szTemp);
if (lpSpec->fScrnFlags & SCRN_SIZEB)
CheckDlgButton (hWnd, IDD_FSIZEDN, TRUE);
else
CheckDlgButton (hWnd, IDD_FSIZEUP, TRUE);
CheckDlgButton (hWnd, IDD_CHKFDATE, lpSpec->fScrnFlags & SCRN_DATE);
Date2asc (lpSpec->usIncDate, 0, szTemp);
*strchr (szTemp, ' ') = '\0'; //Truncate time part of string
SetDlgItemText (hWnd, IDD_FDATE, szTemp);
CheckRadioButton (hWnd, IDD_FDATEB, IDD_FDATEO,
IDD_FDATEB + (lpSpec->fScrnFlags & SCRN_BAE));
CheckDlgButton (hWnd, IDD_CHKFATTRS, lpSpec->fScrnFlags & SCRN_ATTRS);
CheckDlgButton (hWnd, IDD_CHKFARDONLY, lpSpec->usIncFlags & _A_RDONLY);
CheckDlgButton (hWnd, IDD_CHKFAARCH, lpSpec->usIncFlags & _A_ARCH);
CheckDlgButton (hWnd, IDD_CHKFAHIDDEN, lpSpec->usIncFlags & _A_HIDDEN);
CheckDlgButton (hWnd, IDD_CHKFASYSTEM, lpSpec->usIncFlags & _A_SYSTEM);
//Since this procedure is used for different dialog templates,
//use flags in ScrnFlags to config template specific stuff.
if (lpSpec->fScrnFlags & DLG_INCLUDE) {
if (lpSpec->fScrnFlags & SCRN_INCDIRS) {
CheckDlgButton (hWnd, IDD_INCDIRS, TRUE);
EnableWindow (GetDlgItem (hWnd, IDD_INCEMPTYDIRS), TRUE);
if (!(lpSpec->fScrnFlags & SCRN_INCEMPTYDIRS))
CheckDlgButton (hWnd, IDD_INCEMPTYDIRS, TRUE);
} else
EnableWindow (GetDlgItem (hWnd, IDD_INCEMPTYDIRS), FALSE);
//Hide Save As button
ShowWindow (GetDlgItem (hWnd, IDD_SAVEAS), SW_HIDE);
}
return TRUE;
case WM_COMMAND:
switch (wParam) {
case IDD_INCDIRS:
if (IsDlgButtonChecked (hWnd, IDD_INCDIRS))
EnableWindow (GetDlgItem (hWnd, IDD_INCEMPTYDIRS), TRUE);
else {
CheckDlgButton (hWnd, IDD_INCEMPTYDIRS, FALSE);
EnableWindow (GetDlgItem (hWnd, IDD_INCEMPTYDIRS), FALSE);
}
break;
case IDD_SAVEAS:
case IDOK:
if ((lpSpec->fScrnFlags & DLG_INCLUDE) ||
(lpSpec->fScrnFlags & DLG_INCLUDEEDIT))
GetDlgItemText (hWnd, IDD_SPECNAME, lpSpec->szSpecName,
sizeof (lpSpec->szSpecName));
lpSpec->fScrnFlags = 0;
// Get and verify filename spec
if (IsDlgButtonChecked (hWnd, IDD_CHKFSPEC)) {
lpSpec->fScrnFlags |= SCRN_NAME;
GetDlgItemText (hWnd, IDD_FSPEC, szTemp, sizeof (szTemp));
strupr (szTemp);
if (strpbrk (szTemp, ":\\")) {
PrintError (hWnd, ERR_BADNAME);
return TRUE;
}
lstrcpy (lpSpec->szFileSpec, szTemp);
}
// Get and verify size spec
if (IsDlgButtonChecked (hWnd, IDD_CHKFSIZE)) {
GetDlgItemText (hWnd, IDD_FSIZE, szTemp, sizeof (szTemp));
for (i = 0; i < (INT) strlen (szTemp); i++)
if (!isdigit (szTemp[i])) {
PrintError (hWnd, ERR_BADSIZE);
return TRUE;
}
lpSpec->lIncSize = atol (szTemp);
lpSpec->fScrnFlags |= SCRN_SIZE;
if (IsDlgButtonChecked (hWnd, IDD_FSIZEDN))
lpSpec->fScrnFlags |= SCRN_SIZEB;
else
lpSpec->fScrnFlags &= ~SCRN_SIZEB;
}
// Get and verify date spec
if (IsDlgButtonChecked (hWnd, IDD_CHKFDATE)) {
GetDlgItemText (hWnd, IDD_FDATE, szTemp, sizeof (szTemp));
fFail = FALSE;
usDate = 0;
i = atoi (szTemp);
if ((i < 1) || (i > 12))
fFail = TRUE;
else
usDate |= i << 5;
i = 0;
pszTemp = strchr (szTemp, '-');
if (pszTemp)
i = atoi (pszTemp+1);
if ((i < 1) || (i > 31)) //No, I didn't bother to check
fFail = TRUE; //specific month lengths.
else
usDate |= i;
i = -1;
pszTemp = strchr (pszTemp+1, '-');
if (pszTemp)
i = atoi (pszTemp+1) - 1980;
if (i < 0)
fFail = TRUE;
else
usDate |= i << 9;
if (fFail) {
PrintError (hWnd, ERR_BADDATE);
return TRUE;
}
lpSpec->usIncDate = usDate;
lpSpec->fScrnFlags |= SCRN_DATE;
lpSpec->fScrnFlags &= ~SCRN_BAE;
if (IsDlgButtonChecked (hWnd, IDD_FDATEA))
lpSpec->fScrnFlags |= 1;
else if (IsDlgButtonChecked (hWnd, IDD_FDATEO))
lpSpec->fScrnFlags |= 2;
}
// Get and verify attribute spec
if (IsDlgButtonChecked (hWnd, IDD_CHKFATTRS)) {
lpSpec->usIncFlags = 0;
if (IsDlgButtonChecked (hWnd, IDD_CHKFARDONLY))
lpSpec->usIncFlags |= _A_RDONLY;
if (IsDlgButtonChecked (hWnd, IDD_CHKFAARCH))
lpSpec->usIncFlags |= _A_ARCH;
if (IsDlgButtonChecked (hWnd, IDD_CHKFAHIDDEN))
lpSpec->usIncFlags |= _A_HIDDEN;
if (IsDlgButtonChecked (hWnd, IDD_CHKFASYSTEM))
lpSpec->usIncFlags |= _A_SYSTEM;
lpSpec->fScrnFlags |= SCRN_ATTRS;
}
//Check directory flags
if (IsDlgButtonChecked (hWnd, IDD_INCDIRS)) {
lpSpec->fScrnFlags |= SCRN_INCDIRS;
if (IsDlgButtonChecked (hWnd, IDD_INCEMPTYDIRS))
lpSpec->fScrnFlags |= SCRN_INCEMPTYDIRS;
}
if (wParam == IDD_SAVEAS)
EndDialog(hWnd, 2);
else
EndDialog(hWnd, 1);
return TRUE;
case IDCANCEL:
EndDialog(hWnd, 0);
return TRUE;
}
break;
}
return FALSE;
}
//============================================================
// IncludeDelDlgProc - Delete Set dialog box dialog procedure
//============================================================
BOOL CALLBACK IncludeDelDlgProc (HWND hWnd, UINT wMsg, UINT wParam,
LONG lParam) {
INT i;
switch (wMsg) {
case WM_INITDIALOG:
SendDlgItemMessage (hWnd, IDD_INCLIST, LB_RESETCONTENT, 0, 0);
for (i = 1; i < sIncCount; i++)
SendDlgItemMessage (hWnd, IDD_INCLIST, LB_ADDSTRING, 0,
(LONG)(LPSTR)incArray[i].szSpecName);
if (lParam) {
SetDlgItemText (hWnd, IDOK, "Edit");
SetWindowText (hWnd, "Edit Include Set");
}
return TRUE;
case WM_COMMAND:
switch (wParam) {
case IDOK:
i = (INT) SendDlgItemMessage (hWnd, IDD_INCLIST,
LB_GETCURSEL, 0, 0);
if (i == LB_ERR) {
EndDialog(hWnd, 0);
} else
EndDialog(hWnd, i+1);
return TRUE;
case IDCANCEL:
EndDialog(hWnd, 0);
return TRUE;
}
}
return FALSE;
}
//============================================================
// AboutDlgProc - About dialog box dialog procedure
//============================================================
BOOL CALLBACK AboutDlgProc (HWND hWnd, UINT wMsg, UINT wParam,
LONG lParam) {
char szAboutStr[128];
if (wMsg == WM_INITDIALOG) {
GetDlgItemText (hWnd, IDD_PROGSTR, szAboutStr, sizeof (szAboutStr));
itoa ((INT)lParam/10, &szAboutStr[strlen (szAboutStr)], 10);
strcat (szAboutStr, ".");
itoa ((INT)lParam%10, &szAboutStr[strlen (szAboutStr)], 10);
SetDlgItemText (hWnd, IDD_PROGSTR, szAboutStr);
return TRUE;
}
if (wMsg == WM_COMMAND)
if ((wParam == IDOK) || (wParam == IDCANCEL)) {
EndDialog(hWnd, 0);
return TRUE;
}
return FALSE;
}
//------------------------------------------------------------
// GetFListPos - Compute the size and position of the files
// listbox.
//------------------------------------------------------------
void GetFListPos (HWND hWnd, RECT *rectOut) {
RECT rect;
GetClientRect (hWnd, &rect);
ModifyClientRect (hWnd, &rect);
*rectOut = rect;
return;
}
//------------------------------------------------------------
// CopyFile - Copies a file
//------------------------------------------------------------
INT CopyFile (LPMYDIRENTRY lpEntry, char *pszName, char *pszSrc, char *pszDest) {
char szTemp[128];
char szTemp1[128];
char *pszTemp;
char *pszEnd;
OFSTRUCT ofFile;
if (strlen (pszSrc) + strlen (pszDest) > sizeof (szTemp))
return ERR_NAMETOOLONG;
//Create destination file name
strcpy (szTemp, pszDest);
strcat (szTemp, pszName);
pszEnd = strrchr (szTemp, '\\');
//See if dest path exists.
OpenFile (szTemp, &ofFile, OF_EXIST);
if (ofFile.nErrCode == 3) {
*pszEnd = '\0';
//Back up path until a dir is found. rc 3 is path not found.
while (ofFile.nErrCode == 3) {
pszTemp = strrchr (szTemp, '\\');
if (pszTemp == 0) return 3;
if (*(pszTemp-1) == ':')
pszTemp++;
*pszTemp = '\0';
strcpy (szTemp1, szTemp);
strcat (szTemp1, "\\COM");
OpenFile (szTemp1, &ofFile, OF_EXIST);
}
// Make directories until dest dir created
while (szTemp + strlen (szTemp) < pszEnd) {
szTemp[strlen (szTemp)] = '\\';
mkdir (szTemp);
}
*pszEnd = '\\';
}
return MyCopyFile (pszSrc, szTemp);
}
//------------------------------------------------------------
// DeleteFile - Deletes a file
//------------------------------------------------------------
INT DeleteFile (LPMYDIRENTRY lpEntry, char *pszName, char *pszSrc,
char *pszDest) {
INT rc;
rc = remove (pszSrc);
if (rc == 0)
lpEntry->ucAttrib |= ATTR_DELETED;
return rc;
}
//------------------------------------------------------------
// MoveFile - Moves a file
//------------------------------------------------------------
INT MoveFile (LPMYDIRENTRY lpEntry, char *pszName, char *pszSrc,
char *pszDest) {
INT rc;
rc = CopyFile (lpEntry, pszSrc, pszName, pszDest);
if (rc == 0)
rc = DeleteFile (lpEntry, pszSrc, pszName, pszDest);
return rc;
}
//------------------------------------------------------------
// PrintError - Displays a message box with an error code
//------------------------------------------------------------
void PrintError (HWND hWnd, INT rc) {
char szErrStr[80];
char szTemp[12];
if (rc > 0)
rc += DOSERROFFSET;
else
rc = abs (rc);
if (LoadString (hInst, rc, szErrStr, sizeof (szErrStr)) == 0) {
itoa (rc, szTemp, 10);
strcpy (szErrStr, "Error number: ");
strcat (szErrStr, szTemp);
}
MessageBox (hMain, szErrStr, szTitleText, MB_OK | MB_ICONHAND);
return;
}
//------------------------------------------------------------
// AddIncSet - Adds an include set to the include list
//------------------------------------------------------------
INT AddIncSet (HWND hWnd, PINCSPEC pincData) {
INT i, rc;
//If too many specs, overwrite the oldest one
if (sIncCount >= MAXINCSPECS) {
for (i = 1; i < MAXINCSPECS - 1; i++)
incArray[i] = incArray[i+1];
} else
sIncCount++;
if (strlen (pincData->szSpecName) == 0) {
strcpy (pincData->szSpecName, "Set ");
itoa (sIncCount, &pincData->szSpecName[strlen (pincData->szSpecName)], 10);
}
memcpy (&incArray[sIncCount-1], pincData, sizeof (INCSPEC));
lpCurrInc = &incArray[sIncCount-1];
sOldIncCnt = 0; //Force menu regen on next menu init.
//Get include set
rc = GetIncludedFiles (hWnd);
if (rc) {
PrintError (hWnd, rc);
return 0;
}
FillLB (hWnd, 0);
DisplayCurrStatus (hWnd);
return 0;
}
//------------------------------------------------------------
// FillLB - Clears, then refills the hot key listbox
//------------------------------------------------------------
void FillLB (HWND hWnd, INT sStart) {
INT i;
SendDlgItemMessage (hWnd, IDD_FLIST, LB_RESETCONTENT, 0, 0);
if (sStart > sCount - 1)
return;
for (i = sStart; (i < sStart + sListSize) && (i < sCount); i++)
SendDlgItemMessage (hWnd, IDD_FLIST, LB_ADDSTRING, 0,
(LPARAM) (LONG) i);
SetScrollRange (GetDlgItem (hWnd, IDD_FLIST), SB_VERT, 0,
sCount - sListSize, FALSE);
SetScrollPos (GetDlgItem (hWnd, IDD_FLIST), SB_VERT, sStart, TRUE);
return;
}
//------------------------------------------------------------
// DisplayCurrStatus - Creates a text string describing the
// current status, then displays it in the status bar.
//------------------------------------------------------------
void DisplayCurrStatus (HWND hWnd) {
char szTemp[80];
if (sMasterCount == 0)
SetStatusBarText (hWnd, "Select Refresh under the Files menu to list files", 0);
else {
if (sCount <= 1)
SetStatusBarText (hWnd, "No files found", 0);
else {
lstrcpy (szTemp, lpCurrInc->szSpecName);
strcat (szTemp, " sorted by ");
strcat (szTemp, szSortLabel [sSortIndex]);
SetStatusBarText (hWnd, szTemp, 0);
}
ltoa ((LONG) max (sCount-sDirCnt, 0), szTemp, 10);
if (lpCurrInc->fScrnFlags & SCRN_INCDIRS) {
itoa (sCount, szTemp, 10);
strcat (szTemp, " Directories and files");
} else {
itoa (max (sCount-sDirCnt, 0), szTemp, 10);
strcat (szTemp, " Files");
}
SetStatusBarText (hWnd, szTemp, 1);
}
return;
}
//------------------------------------------------------------
// The following routines are used to convert find data to
// ASCII text strings
//------------------------------------------------------------
//------------------------------------------------------------
// CreatePath - Builds a path string
//------------------------------------------------------------
void CreatePath (LPMYDIRENTRY lpEntry, char *pszOut, int *psSize) {
INT i;
if (lpEntry->lpParent) {
CreatePath (lpEntry->lpParent, pszOut, psSize);
} else {
lstrcat (pszOut, lpEntry->szName+1);
pszOut[2] = 0;
return;
}
i = lstrlen (lpEntry->szName);
if (*psSize < i) {
*psSize = 0;
return;
}
strcat (pszOut, "\\");
lstrcat (pszOut, lpEntry->szName);
*psSize -= (i+1);
return;
}
//------------------------------------------------------------
// Date2asc - Convert DOS date to ASCII string
// Date Time
// 15-9 Year 15-11 Hours
// 8-5 Month 10-5 Minutes
// 4-0 Day 4-0 Seconds * 2
//------------------------------------------------------------
void Date2asc (UINT usDate, UINT usTime, char *pszOut) {
UINT usTemp;
if (usDate == 0xffff) {
*pszOut = '\0';
return;
}
*pszOut++ = (char)((((usDate >> 5) & 0x0f) / 10) + 0x30);
*pszOut++ = (char)((((usDate >> 5) & 0x0f) % 10) + 0x30);
*pszOut++ = '-';
*pszOut++ = (char)(((usDate & 0x1f) / 10) + 0x30);
*pszOut++ = (char)(((usDate & 0x1f) % 10) + 0x30);
*pszOut++ = '-';
usTemp = ((usDate >> 9) & 0x7f) + 1980;
itoa ((INT) usTemp, pszOut, 10);
pszOut += 4;
*pszOut++ = ' ';
*pszOut++ = ' ';
*pszOut++ = ' ';
*pszOut++ = ' ';
usTemp = ((usTime >> 11) & 0x1f);
if (usTemp > 11)
*(pszOut+5) = 'p';
else
*(pszOut+5) = 'a';
if (usTemp > 12)
usTemp -= 12;
*pszOut++ = (char)((usTemp / 10) + 0x30);
*pszOut++ = (char)((usTemp % 10) + 0x30);
*pszOut++ = ':';
usTemp = ((usTime >> 5) & 0x3f);
*pszOut++ = (char)((usTemp / 10) + 0x30);
*pszOut++ = (char)((usTemp % 10) + 0x30);
//Seconds are not displayed
*(pszOut+1) = '\0';
return;
}
//------------------------------------------------------------
// Attr2asc - Convert DOS attribute flags to ASCII string
//------------------------------------------------------------
void Attr2asc (BYTE ucAttrib, char *pszOut) {
strcpy (pszOut, "----");
if (ucAttrib & _A_RDONLY)
*pszOut = 'r';
pszOut++;
if (ucAttrib & _A_ARCH)
*pszOut = 'a';
pszOut++;
if (ucAttrib & _A_SYSTEM)
*pszOut = 's';
pszOut++;
if (ucAttrib & _A_HIDDEN)
*pszOut = 'h';
return;
}
//------------------------------------------------------------
// The following routines are used by the Find and include
// set functions.
//------------------------------------------------------------
//------------------------------------------------------------
// ScreenFile - Determines if a file entry matches a set of
// characteristics.
//------------------------------------------------------------
BOOL ScreenFile (LPMYDIRENTRY lpEntry, LPINCSPEC lpSpec) {
BOOL fInclude = TRUE;
char far *lpTemplate;
char far *lpName;
//See if file already deleted.
if (lpEntry->ucAttrib & ATTR_DELETED)
return FALSE;
//Check file name
if (lpSpec->fScrnFlags & SCRN_NAME) {
lpName = lpEntry->szName;
lpTemplate = lpSpec->szFileSpec;
while (fInclude && (*lpTemplate != '\0')) {
if (*lpTemplate == '?') {
;
} else if (*lpTemplate == '*') {
while ((*lpName != '\0') &&
(*lpName != *(lpTemplate+1)))
lpName++;
lpTemplate++;
} else
if (*lpName != *lpTemplate)
fInclude = FALSE;
lpTemplate++;
if (*lpName != '\0')
lpName++;
}
}
//Check file date
if (fInclude && (lpSpec->fScrnFlags & SCRN_DATE)) {
switch (lpSpec->fScrnFlags & SCRN_BAE) {
case 0:
if (lpEntry->usDate > lpSpec->usIncDate)
fInclude = FALSE;
break;
case 1:
if (lpEntry->usDate < lpSpec->usIncDate)
fInclude = FALSE;
break;
case 2:
if (lpEntry->usDate != lpSpec->usIncDate)
fInclude = FALSE;
break;
}
}
//Check file size
if (fInclude && (lpSpec->fScrnFlags & SCRN_SIZE)) {
if (lpSpec->fScrnFlags & SCRN_SIZEB) {
if (lpEntry->lSize >= lpSpec->lIncSize)
fInclude = FALSE;
} else {
if (lpEntry->lSize < lpSpec->lIncSize)
fInclude = FALSE;
}
}
//Check file attributes
if (fInclude && (lpSpec->fScrnFlags & SCRN_ATTRS)) {
if (!(lpEntry->ucAttrib & (BYTE) lpSpec->usIncFlags))
fInclude = FALSE;
}
return fInclude;
}
//------------------------------------------------------------
// GetIncludedDir - Scans a directory for files matching the
// requested criteria.
//------------------------------------------------------------
INT GetIncludedDir (LPMYDIRENTRY lpParent, LPLPMYDIRENTRY lpEndPtr,
INT *psNum) {
INT sSubNum;
LPMYDIRENTRY lpEntryPtr;
lpEntryPtr = *lpIndexPtr;
while ((lpEndPtr > lpIndexPtr) &&
(lpEntryPtr->lpParent == lpParent)) {
lpIndexPtr++;
if (lpEntryPtr->ucAttrib & _A_SUBDIR) {
lpEntryPtr->lSize = 0;
lpEntryPtr->usDate = 0;
lpEntryPtr->usTime = 0;
sSubNum = 0;
GetIncludedDir (lpEntryPtr, lpEndPtr, &sSubNum);
if ((lpCurrInc->fScrnFlags & SCRN_INCDIRS) &&
(sSubNum || (lpCurrInc->fScrnFlags & SCRN_INCEMPTYDIRS))) {
*lpDestPtr++ = lpEntryPtr;
sSubNum++;
sDirCnt++;
}
lpParent->lSize += lpEntryPtr->lSize;
if (sSubNum) {
if ((lpParent->usDate < lpEntryPtr->usDate) ||
((lpParent->usDate == lpEntryPtr->usDate) &&
(lpParent->usTime < lpEntryPtr->usTime))) {
lpParent->usDate = lpEntryPtr->usDate;
lpParent->usTime = lpEntryPtr->usTime;
}
}
*psNum += sSubNum;
} else {
if (ScreenFile (lpEntryPtr, lpCurrInc)) {
*lpDestPtr++ = lpEntryPtr;
//Add file size to that of parent. Update date as well.
lpParent->lSize += lpEntryPtr->lSize;
if ((lpParent->usDate < lpEntryPtr->usDate) ||
((lpParent->usDate == lpEntryPtr->usDate) &&
(lpParent->usTime < lpEntryPtr->usTime))) {
lpParent->usDate = lpEntryPtr->usDate;
lpParent->usTime = lpEntryPtr->usTime;
}
(*psNum)++;
}
}
lpEntryPtr = *lpIndexPtr;
}
return 0;
}
//------------------------------------------------------------
// GetIncludedSet - Creates a subset index array that matches the
// current include spec characteristics.
//------------------------------------------------------------
HGLOBAL GetIncludedSet (LPMYDIRENTRY lpStartDir, INT *psCnt) {
HGLOBAL hGlobal;
INT i;
LPLPMYDIRENTRY lpEndPtr;
if (sMasterCount == 0)
return 0;
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hMasterSeg);
lpEndPtr = lpIndexPtr + sMasterCount - 1;
for (i = 0;i < sMasterCount; i++)
if (*lpIndexPtr++ == lpStartDir)
break;
hGlobal = GlobalAlloc (GHND, (LONG)(sMasterCount - i) *
sizeof (LPMYDIRENTRY));
if (hGlobal == 0)
return 0;
lpDestPtr = (LPLPMYDIRENTRY) GlobalLock (hGlobal);
*psCnt = 0;
GetIncludedDir (lpStartDir, lpEndPtr, psCnt);
GlobalUnlock (hGlobal);
GlobalUnlock (hMasterSeg);
return hGlobal;
}
//------------------------------------------------------------
// GetIncludedFiles - Creates an index array that matches the
// current include spec characteristics.
//------------------------------------------------------------
INT GetIncludedFiles (HWND hWnd) {
INT i, rc = 0, sSubNum;
LPLPMYDIRENTRY lpEndPtr;
LPMYDIRENTRY lpHeaderPtr;
LPMYDIRENTRY lpEntryPtr;
//Free all sorted arrays
for (i = 0; i < SORTTYPES; i++)
if (hSortSeg[i]) {
GlobalFree (hSortSeg[i]);
hSortSeg[i] = 0;
}
if (sMasterCount == 0)
return 0;
hSortSeg[sSortIndex] = GlobalAlloc (GHND, (LONG)sMasterCount *
sizeof (LPMYDIRENTRY));
if (hSortSeg[sSortIndex] == 0)
return ERR_OUTOFMEM;
lpDestPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hMasterSeg);
SetStatusBarText (hWnd, "Screening files...", 0);
lpEndPtr = lpIndexPtr + sMasterCount - 1;
lpHeaderPtr = *lpIndexPtr;
*lpDestPtr++ = *lpIndexPtr++; //Copy Search header entry
lpHeaderPtr->lSize = 0;
lpHeaderPtr->usDate = 0;
lpHeaderPtr->usTime = 0;
sCount = 1;
sDirCnt = 1;
lpEntryPtr = *lpIndexPtr++;
while (lpEndPtr > lpIndexPtr) {
lpEntryPtr->lSize = 0;
lpEntryPtr->usDate = 0;
lpEntryPtr->usTime = 0;
sSubNum = 0;
GetIncludedDir (lpEntryPtr, lpEndPtr, &sSubNum);
if (sSubNum) {
*lpDestPtr++ = lpEntryPtr;
sSubNum++;
}
lpHeaderPtr->lSize += lpEntryPtr->lSize;
if ((lpHeaderPtr->usDate < lpEntryPtr->usDate) ||
((lpHeaderPtr->usDate == lpEntryPtr->usDate) &&
(lpHeaderPtr->usTime < lpEntryPtr->usTime))) {
lpHeaderPtr->usDate = lpEntryPtr->usDate;
lpHeaderPtr->usTime = lpEntryPtr->usTime;
}
sCount += sSubNum;
sDirCnt++;
lpEntryPtr = *lpIndexPtr++;
}
GlobalUnlock (hMasterSeg);
GlobalUnlock (hSortSeg[sSortIndex]);
if (sCount) {
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hSortSeg[sSortIndex]);
rc = MyQSort (lpIndexPtr, sCount, (PSORTFUNC) pSortFunc[sSortIndex]);
GlobalUnlock (hSortSeg[sSortIndex]);
}
return rc;
}
//============================================================
// Scan and sort routines
//============================================================
//------------------------------------------------------------
// FreeBuffer - Frees all buffers
//------------------------------------------------------------
INT FreeBuffer (UINT selBuffIn) {
LPBUFFHDR lpBuffPtr;
UINT selNext;
while (selBuffIn) {
lpBuffPtr = MAKELP (selBuffIn, 0);
selNext = lpBuffPtr->selNext;
GlobalUnlock (selBuffIn);
GlobalFree (selBuffIn);
selBuffIn = selNext;
}
return 0;
}
//------------------------------------------------------------
// GetBuffBlock - Allocates and inits a buffer.
//------------------------------------------------------------
INT GetBuffBlock (LPBUFFHDR lpBuff, UINT usOldSize) {
HGLOBAL hMem;
UINT usSize;
LPBUFFHDR lpNewBuff;
usSize = ((0x10000 - sizeof (BUFFHDR)) / sizeof (MYDIRENTRY)) *
sizeof (MYDIRENTRY);
hMem = GlobalAlloc (GHND, usSize);
if (hMem == 0)
return ERR_OUTOFMEM;
lpNewBuff = (LPBUFFHDR) GlobalLock (hMem);
lpBuff->selNext = SELECTOROF (lpNewBuff);
lpBuff->usEnd = usOldSize;
lpNewBuff->usSize = usSize;
lpCurrBuff = MAKELP (SELECTOROF (lpNewBuff), 0);
lpDirEntry = (LPMYDIRENTRY) (lpCurrBuff + 1);
return 0;
}
//------------------------------------------------------------
// ScanDir - Copies the contents of a directory into the
// file name buffer.
//------------------------------------------------------------
INT ScanDir (HWND hWnd, LPMYDIRENTRY lpParent) {
FIND_T fs;
char *pszSrchDirEnd;
int i, rc;
UINT far *lpwDest;
UINT *pwSrc;
pszSrchDirEnd = szSearchDir + strlen (szSearchDir);
strcpy (pszSrchDirEnd, "\\*.*");
rc = _dos_findfirst (szSearchDir, _A_RDONLY | _A_ARCH |
_A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &fs);
while ((rc == 0) && (fSearching)) {
//
//Display directory count as a progress report
//
if ((sDirCnt % 20) == 0) {
ltoa (sDirCnt, pszStatEnd, 10);
SetDlgItemText (hWnd, IDD_REFRESHTEXT, szStatText);
}
MyYield (); //Yield to other apps
if (!fSearching)
return ERR_CANCELED;
//
// See if current buffer filled
//
lpDirEntry++;
if (OFFSETOF (lpDirEntry) >= lpCurrBuff->usSize) {
rc = GetBuffBlock (lpCurrBuff, OFFSETOF (lpDirEntry));
if (rc)
return rc;
}
//
// Copy directory entry
//
pwSrc = (UINT *) &fs.attrib;
lpwDest = (UINT far *)lpDirEntry;
//Save parent pointer
*((LPLONG)lpwDest)++ = (LONG)lpParent;
//Copy Dir entry
for (i = 2; i < sizeof (MYDIRENTRY)/2; i++)
*lpwDest++ = *pwSrc++;
//Clear flags I hide in attribute byte
lpDirEntry->ucAttrib &= ~(ATTR_DELETED | ATTR_SELECTED);
//
//If subdir, recurse
//
if (fs.attrib & _A_SUBDIR) {
sDirCnt++;
if ((strcmp (fs.name, ".") != 0) &&
(strcmp (fs.name, "..") != 0)) {
*lpIndexPtr++ = lpDirEntry;
sMasterCount++;
*pszSrchDirEnd = '\\';
strcpy (pszSrchDirEnd+1, fs.name);
rc = ScanDir (hWnd, lpDirEntry);
if (rc == 0x12)
rc = 0;
}
} else {
*lpIndexPtr++ = lpDirEntry;
sMasterCount++;
}
//
// Add entry to index
//
if (sMasterCount > MAXCOUNT)
rc = ERR_TOOMANYFILES;
if (rc == 0)
rc = _dos_findnext (&fs);
}
return rc;
}
//------------------------------------------------------------
// ScanDisk - Search a specific drive
//------------------------------------------------------------
INT ScanDisk (HWND hWnd, LPMYDIRENTRY lpParent, INT sDiskNum) {
INT rc;
LPMYDIRENTRY lpDrvEntry;
lpDirEntry++;
if (OFFSETOF (lpDirEntry) >= lpCurrBuff->usSize) {
rc = GetBuffBlock (lpCurrBuff, OFFSETOF (lpDirEntry));
if (rc)
return rc;
}
sMasterCount++;
if (sMasterCount > MAXCOUNT)
rc = ERR_TOOMANYFILES;
*lpIndexPtr++ = lpDirEntry;
lpDrvEntry = lpDirEntry;
lpDrvEntry->lpParent = 0;
lpDrvEntry->ucAttrib = ATTR_DELETED;
lpDrvEntry->usTime = 0;
lpDrvEntry->usDate = 0;
lpDrvEntry->lSize = 0;
lstrcpy (lpDrvEntry->szName, " C:\\");
lpDrvEntry->szName[1] = (char) (sDiskNum + 0x40);
_chdrive (sDiskNum);
chdir ("\\");
szSearchDir[0] = '\0';
rc = ScanDir (hWnd, lpDirEntry);
lpParent->lSize += lpDrvEntry->lSize;
return rc;
}
//------------------------------------------------------------
// ScanMachine - Performs the entire search
//------------------------------------------------------------
INT ScanMachine (HWND hWnd, INT sCnt, INT *sDrives) {
INT i, rc;
char szDrv[10];
LPMYDIRENTRY lpSrchEntry;
//Free old buffers
FreeBuffer (Buff.selNext);
if (hMasterSeg)
GlobalFree (hMasterSeg);
for (i = 0; i < SORTTYPES; i++)
if (hSortSeg[i]) {
GlobalFree (hSortSeg[i]);
hSortSeg[i] = 0;
}
//Alloc buffs for dir entries and index
rc = GetBuffBlock (&Buff, 0);
if (rc)
return rc;
hMasterSeg = GlobalAlloc (GHND, (LONG)MAXCOUNT * sizeof (LPLPMYDIRENTRY));
if (hMasterSeg == 0)
rc = ERR_OUTOFMEM;
sMasterCount = 1;
fSearching = TRUE;
lpIndexPtr = (LPLPMYDIRENTRY) GlobalLock (hMasterSeg);
*lpIndexPtr++ = lpDirEntry;
lpSrchEntry = lpDirEntry;
lpSrchEntry->lpParent = 0;
lpSrchEntry->ucAttrib = ATTR_DELETED;
lpSrchEntry->usTime = 0;
lpSrchEntry->usDate = 0;
lpSrchEntry->lSize = 0;
lstrcpy (lpSrchEntry->szName, " Search");
for (i = 0; (i < sCnt) && (rc == 0); i++) {
SendDlgItemMessage (hWnd, IDD_DRVLIST, LB_GETTEXT, sDrives[i],
(LONG)(LPSTR)szDrv);
strcpy (szStatText, "Scanning Disk ");
strcat (szStatText, szDrv);
SetDlgItemText (hWnd, IDD_REFRESHTEXT, szStatText);
strcat (szStatText, "\nDirs: ");
pszStatEnd = szStatText + strlen (szStatText);
strupr (szDrv);
rc = ScanDisk (hWnd, lpSrchEntry, szDrv[2]-(BYTE)0x40);
if (rc == 0x12)
rc = 0;
}
GlobalUnlock (hMasterSeg);
fSearching = FALSE;
//Shrink the index block down to size necessary.
hMasterSeg = GlobalReAlloc (hMasterSeg, (LONG)sMasterCount *
sizeof (LPLPMYDIRENTRY), GMEM_ZEROINIT);
if (hMasterSeg == 0)
rc = ERR_OUTOFMEM;
return rc;
}
//------------------------------------------------------------
// InvertIndex - Invert an index
//------------------------------------------------------------
void InvertIndex (HPDWORD lpSrc, UINT usCnt) {
DWORD dwTemp;
HPDWORD lpDest;
lpDest = lpSrc + usCnt - 1;
while (lpDest >= lpSrc) {
dwTemp = *lpDest;
*lpDest = *lpSrc;
*lpSrc = dwTemp;
lpSrc++;
lpDest--;
}
return;
}
//------------------------------------------------------------
// SortDate - Sorts entries by file date
//------------------------------------------------------------
INT SortDate (LPVOID lpSrc, LPVOID lpDest) {
UINT usTemp;
usTemp = ((LPMYDIRENTRY)*(LPDWORD)lpDest)->usDate -
((LPMYDIRENTRY)*(LPDWORD)lpSrc)->usDate;
if (usTemp)
return (INT) usTemp;
usTemp = ((LPMYDIRENTRY)*(LPDWORD)lpDest)->usTime -
((LPMYDIRENTRY)*(LPDWORD)lpSrc)->usTime;
if (usTemp)
return (INT) usTemp;
return SortName (lpSrc, lpDest);
}
//------------------------------------------------------------
// SortSize - Sorts entries by file size
//------------------------------------------------------------
INT SortSize (LPVOID lpSrc, LPVOID lpDest) {
LONG lTemp;
lTemp = ((LPMYDIRENTRY)*(LPDWORD)lpDest)->lSize -
((LPMYDIRENTRY)*(LPDWORD)lpSrc)->lSize;
if (lTemp < 0)
return -1;
if (lTemp > 0)
return 1;
return SortName (lpSrc, lpDest);
}
//------------------------------------------------------------
// SortExt - Sorts entries by file ext
//------------------------------------------------------------
INT SortExt (LPVOID lpSrc, LPVOID lpDest) {
char far *pszSrc, far *pszDest;
INT rc;
pszSrc = ((LPMYDIRENTRY)*(LPDWORD)lpSrc)->szName;
pszDest = ((LPMYDIRENTRY)*(LPDWORD)lpDest)->szName;
while ((*pszSrc != '\0') && (*pszSrc != '.'))
pszSrc++;
while ((*pszDest != '\0') && (*pszDest != '.'))
pszDest++;
rc = lstrcmp (pszSrc,pszDest);
if (rc)
return rc;
return SortName (lpSrc, lpDest);
}
//------------------------------------------------------------
// SortName - Sorts entries by filename
//------------------------------------------------------------
INT SortName (LPVOID lpSrc, LPVOID lpDest) {
return lstrcmp (((LPMYDIRENTRY)*(LPDWORD)lpSrc)->szName,
((LPMYDIRENTRY)*(LPDWORD)lpDest)->szName);
}
//------------------------------------------------------------
// MyQSort1 - A quick sort routine
//------------------------------------------------------------
INT MyQSort1 (HPDWORD lpBase, UINT usNum, PSORTFUNC pFunc) {
INT rc;
UINT usHigh, usEven, usLow;
HPDWORD lpHigh, lpLow;
DWORD dwPiv, dwVal;
usLevel++;
if (usLevel > 500)
return ERR_TOODEEP;
//Compute and display status
usItteration++;
usHigh = (UINT) ((LONG) usItteration/(LONG)usGoal);
if (((usHigh % 5) == 0) && (usLastStat != usHigh)) {
usLastStat = usHigh;
ltoa (usHigh, pszStatEnd, 10);
strcat (pszStatEnd, "%");
SetStatusBarText (hMain, szStatText, 0);
}
//Yield to other apps
MyYield ();
if (!fSearching)
return ERR_CANCELED;
lpLow = lpBase;
lpHigh = lpBase + (usNum - 1);
//Pick random Pivot. Choose 1st element for simplicity
dwPiv = *lpLow;
dwVal = *lpHigh;
usLow = usEven = 0;
//Move smaller elements above pivot
while (lpLow < lpHigh) {
rc = ((SORTFUNC)pFunc)(&dwPiv, &dwVal);
if (rc >= 0) {
*lpLow++ = dwVal;
dwVal = *lpLow;
usLow++;
if (rc == 0)
usEven++;
} else {
*lpHigh-- = dwVal;
dwVal = *lpHigh;
}
}
*lpLow++ = dwPiv;
usHigh = usNum - usLow;
rc = 0;
//if more that two below, sort elements below pivot
if (usLow > 1)
rc = MyQSort1 (lpBase, usLow, pFunc);
//if more that two above, sort elements above pivot
if ((usHigh > 2) && (rc == 0))
rc = MyQSort1 (lpLow, usHigh-1, pFunc);
usLevel--;
return rc;
}
//------------------------------------------------------------
// MyQSort - QuickSort setup routine
//------------------------------------------------------------
INT MyQSort (HPDWORD lpBase, UINT usNum, PSORTFUNC pFunc) {
INT rc;
if (usNum < 2)
return 0;
fSearching = TRUE;
usItteration = 0;
usLevel = 0;
usLastStat = -1;
usGoal = (sCount / 138) + 1;
strcpy (szStatText, "Sorting ");
pszStatEnd = szStatText + strlen (szStatText);
rc = MyQSort1 (lpBase, usNum, pFunc);
if (fSortUp)
InvertIndex (lpBase, usNum);
fSearching = FALSE;
return rc;
}
//============================================================
// General Helper Routines
//============================================================
//------------------------------------------------------------
// MyDisplayDialog - Display a dialog box
//------------------------------------------------------------
INT MyDisplayDialog (HINSTANCE hInstance, LPCSTR szDlgName,
HWND hWnd, WNDPROC lpDialogProc,
LPARAM lParam) {
WNDPROC lpDlgProcInst;
INT rc;
lpDlgProcInst = MakeProcInstance(lpDialogProc, hInst);
rc = DialogBoxParam (hInstance, szDlgName, hWnd,
lpDlgProcInst, lParam);
FreeProcInstance(lpDlgProcInst);
return rc;
}
//------------------------------------------------------------
// MyWritePrivateProfileInt - Writes an integer to the profile
//------------------------------------------------------------
BOOL MyWritePrivateProfileInt (char *szSec, char *szEntry,
int Num, int Base, char *szProfile) {
char szStr[33];
itoa (Num, szStr, Base);
return WritePrivateProfileString (szSec, szEntry, szStr,
szProfile);
}
//------------------------------------------------------------
// MySubClassWindow - Subclasses a window
//------------------------------------------------------------
WNDPROC MySubClassWindow (HWND hWnd, WNDPROC lpfnNewProc) {
WNDPROC lpfnOldProc;
lpfnOldProc = (WNDPROC) GetWindowLong (hWnd, GWL_WNDPROC);
SetWindowLong (hWnd, GWL_WNDPROC, (LONG) lpfnNewProc);
return lpfnOldProc;
}
//------------------------------------------------------------
// MyYield - Yields control to other programs, but returns
// if Windows is idle.
//------------------------------------------------------------
BOOL MyYield (void) {
MSG msg;
BOOL bCont;
bCont = TRUE;
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
bCont = FALSE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return bCont;
}
//------------------------------------------------------------
// MyCopyFile - Copy a file
//------------------------------------------------------------
#define COPYBUFFSIZE 0xf000
INT MyCopyFile (char *szSrcFile, char *szDestFile) {
int rc, i;
HFILE hSrc, hDest;
HGLOBAL hMem;
UINT usByteCnt;
OFSTRUCT ofFile;
LPSTR lpBuffer;
DOSERR doserr;
// Open Source file
hSrc = OpenFile (szSrcFile, &ofFile, OF_READ);
if (hSrc == -1)
return ofFile.nErrCode;
// Open Destination file, first, append src filename.
i = strlen (szDestFile);
if (szDestFile[i-1] != '\\')
strcat (szDestFile, strrchr (szSrcFile, '\\'));
else
strcat (szDestFile, strrchr (szSrcFile, '\\')+1);
hDest = OpenFile (szDestFile, &ofFile, OF_CREATE);
if (hDest == -1) {
// If path not found error, delete src filename
if (ofFile.nErrCode == 3) {
szDestFile[i] ='\0';
hDest = OpenFile (szDestFile, &ofFile, OF_CREATE);
}
if (hDest == -1) {
_lclose (hSrc);
return ofFile.nErrCode;
}
}
// Allocate memory for a copy buffer
rc = 0;
hMem = GlobalAlloc (GHND, (LONG) COPYBUFFSIZE);
if (hMem != 0) {
lpBuffer = GlobalLock (hMem);
while (rc == 0) {
usByteCnt = _lread (hSrc, lpBuffer, COPYBUFFSIZE);
if (usByteCnt == 0xFFFF)
rc = dosexterr (&doserr);
else {
usByteCnt = _lwrite (hDest, lpBuffer, usByteCnt);
if (usByteCnt == 0xFFFF)
rc = dosexterr (&doserr);
}
if (usByteCnt < COPYBUFFSIZE)
break;
}
// Clean up
GlobalUnlock (hMem);
GlobalFree (hMem);
} else
rc = ERR_OUTOFMEM;
_lclose (hSrc);
_lclose (hDest);
return rc;
}